!pip install pandas matplotlib numpy statsmodels seaborn scipy -q
[notice] A new release of pip is available: 24.3.1 -> 25.1.1 [notice] To update, run: pip install --upgrade pip
# Import all datasets for sit to stand
import pandas as pd
from data_collector import get_sit_to_stand_paths, get_sit_to_stand_challenge_paths, get_water_task_paths, get_water_task_challenge_paths, get_step_count_paths, get_step_count_challenge_paths
import numpy as np
task = 'sit2stand'
if task == 'sit2stand':
paths_standard = get_sit_to_stand_paths()
paths_challenge = get_sit_to_stand_challenge_paths()
elif task == 'water':
paths_standard = get_water_task_paths()
paths_challenge = get_water_task_challenge_paths()
elif task == 'step_count':
paths_standard = get_step_count_paths()
paths_challenge = get_step_count_challenge_paths()
dfs_stand = [pd.read_csv(path) for path in paths_standard]
dfs_stand_challenge = [pd.read_csv(path) for path in paths_challenge]
# For each dataframe, add a new column 'time_s' which is the time in seconds from the first timestamp
for df in dfs_stand:
df['time_s'] = (df['timestamp_ms'] - df['timestamp_ms'].min()) / 1000
for df in dfs_stand_challenge:
df['time_s'] = (df['timestamp_ms'] - df['timestamp_ms'].min()) / 1000
if task=='step_count':
# rename column from acceleration_m/s²_x to 'freeAcceleration_m/s²_x' for x y and z
dfs_stand = [df.rename(columns={'acceleration_m/s²_x': 'freeAcceleration_m/s²_x', 'acceleration_m/s²_y': 'freeAcceleration_m/s²_y', 'acceleration_m/s²_z': 'freeAcceleration_m/s²_z'}) for df in dfs_stand]
dfs_stand_challenge = [df.rename(columns={'acceleration_m/s²_x': 'freeAcceleration_m/s²_x', 'acceleration_m/s²_y': 'freeAcceleration_m/s²_y', 'acceleration_m/s²_z': 'freeAcceleration_m/s²_z'}) for df in dfs_stand_challenge]
# Calculate magnitude of acceleration
for df in dfs_stand:
df['acceleration_magnitude'] = np.sqrt(
df['freeAcceleration_m/s²_x']**2 +
df['freeAcceleration_m/s²_y']**2 +
df['freeAcceleration_m/s²_z']**2
)
for df in dfs_stand_challenge:
df['acceleration_magnitude'] = np.sqrt(
df['freeAcceleration_m/s²_x']**2 +
df['freeAcceleration_m/s²_y']**2 +
df['freeAcceleration_m/s²_z']**2
)
df_standard = dfs_stand[0]
df_challenge = dfs_stand_challenge[0]
print(f"Using data from {paths_standard[0]} and {paths_challenge[0]}")
Data directory to look in: /Users/ashish/Desktop/DS4W/sensorhub-analysis/data Sub directories for each Device ID found: ['f3eba7e5-dbda-4f4c-9fa8-8e8308b334f6', '5f680dfb-2510-4790-8f10-cb8724e7004c', '3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8'] Data directory to look in: /Users/ashish/Desktop/DS4W/sensorhub-analysis/data Sub directories for each Device ID found: ['f3eba7e5-dbda-4f4c-9fa8-8e8308b334f6', '5f680dfb-2510-4790-8f10-cb8724e7004c', '3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8'] Using data from /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-08T12_59_06Z-sit_to_stand/sit_to_stand_imu.csv and /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T06_58_28Z-sit_to_stand_challenge/sit_to_stand_imu.csv
Experimental Design¶
Within-subject study: Each participant (N = 5) performs:
- Sit-to-stand under normal conditions
- Sit-to-stand while doing a cognitive task (serial subtraction)
Data collected:
- Timestamped acceleration on 3 axes (x, y, z) for ~30 seconds per trial
Step 1: Compute Acceleration Magnitude¶
We reduce the 3D accelerometer signal into a single scalar by computing the magnitude of free acceleration at each time point:
$$ \text{acc_mag}(t) = \sqrt{x_t^2 + y_t^2 + z_t^2} $$
This gives us a time-series that reflects total body movement intensity.
Step 2: Feature Extraction : Mean Acceleration¶
We summarize the signal for each trial (one per participant per condition) by computing the mean acceleration magnitude:
$$ \bar{a} = \frac{1}{T} \sum_{t=1}^{T} \text{acc_mag}(t) $$
Where:
- T is the number of time points in the trial
- a' represents the average movement intensity
🔍 Step 3: Statistical Testing : Paired t-test¶
To assess whether the cognitive condition affects mean acceleration, we compare the values within participants using a paired t-test.
Let the difference for each participant be:
$$ D_i = a_{\text{normal},i} - a_{\text{cognitive},i} $$
We test the null hypothesis:
$$ H_0: \mu_D = 0 \quad \text{(no difference)} $$
With the t-statistic:
$$ t = \frac{\bar{D}}{s_D / \sqrt{n}} $$
Where:
- D' is the mean of the differences
- s_D is the standard deviation of the differences
- n is the number of participants
If the resulting p-value < 0.05, we reject ( H_0 ), concluding that cognitive load significantly alters movement.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
# Convert timestamps to datetime for better x-axis labels
# Create a relative time in seconds from the first timestamp
def visualize_data(df):
# Plot the acceleration data
plt.figure(figsize=(12, 8))
# Plot each axis
plt.subplot(3, 1, 1)
plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='X-axis')
plt.ylabel('Acceleration (m/s²)')
plt.title('Free Acceleration X-axis')
plt.grid(True)
plt.legend()
plt.subplot(3, 1, 2)
plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'g-', label='Y-axis')
plt.ylabel('Acceleration (m/s²)')
plt.title('Free Acceleration Y-axis')
plt.grid(True)
plt.legend()
plt.subplot(3, 1, 3)
plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'b-', label='Z-axis')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('Free Acceleration Z-axis')
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
# Combined view of all three axes
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='X-axis')
plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'g-', label='Y-axis')
plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'b-', label='Z-axis')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('Free Acceleration - All Axes')
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
# Plot the magnitude
plt.figure(figsize=(12, 5))
plt.plot(df['time_s'], df['acceleration_magnitude'], 'k-')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration Magnitude (m/s²)')
plt.title('Magnitude of Acceleration')
plt.grid(True)
plt.tight_layout()
plt.show()
# Visualize normal data
visualize_data(df_standard)
# Visualize challenge data
visualize_data(df_challenge)
# Compare both data x-axis acceleration
def compare_acceleration_x(df, df_challenge):
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='Normal')
plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_x'], 'b-', label='Challenge')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('X-axis Acceleration Comparison')
plt.legend()
plt.show()
# Compare both data x-axis acceleration
compare_acceleration_x(df_standard, df_challenge)
# Compare both data y-axis acceleration
def compare_acceleration_y(df, df_challenge):
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'r-', label='Normal')
plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_y'], 'b-', label='Challenge')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('Y-axis Acceleration Comparison')
plt.legend()
plt.show()
# Compare both data y-axis acceleration
compare_acceleration_y(df_standard, df_challenge)
# Compare both data z-axis acceleration
def compare_acceleration_z(df, df_challenge):
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'r-', label='Normal')
plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_z'], 'b-', label='Challenge')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('Y-axis Acceleration Comparison')
plt.legend()
plt.show()
# Compare both data z-axis acceleration
compare_acceleration_z(df_standard, df_challenge)
# Compare both data magnitude of acceleration
def compare_acceleration_magnitude(df, df_challenge):
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['acceleration_magnitude'], 'r-', label='Normal')
plt.plot(df_challenge['time_s'], df_challenge['acceleration_magnitude'], 'b-', label='Challenge')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration Magnitude (m/s²)')
plt.title('Magnitude of Acceleration Comparison')
plt.legend()
plt.show()
# Compare both data magnitude of acceleration
compare_acceleration_magnitude(df_standard, df_challenge)
# Compare x-acceleration across all participants
def compare_acceleration_x_all(dfs, axis='x'):
plt.figure(figsize=(20, 6))
for i, df in enumerate(dfs):
plt.plot(df['time_s'], df[f'freeAcceleration_m/s²_{axis}'], label=f'Participant {i+1}')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title(f'{axis}-axis Acceleration Comparison')
plt.legend()
plt.show()
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand)
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand, 'y')
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand, 'z')
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'x')
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'y')
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'z')
len(dfs_stand), dfs_stand
(5,
[ timestamp_ms timestamp_μs freeAcceleration_m/s²_x \
0 1746709146601 231101705 -0.390118
1 1746709146618 231118372 -0.103113
2 1746709146634 231135039 0.693871
3 1746709146651 231151706 0.976024
4 1746709146668 231168373 0.641669
... ... ... ...
1778 1746709176235 260735631 0.444211
1779 1746709176252 260752298 0.499439
1780 1746709176268 260768965 0.407235
1781 1746709176285 260785632 0.912732
1782 1746709176302 260802299 1.244095
freeAcceleration_m/s²_y freeAcceleration_m/s²_z time_s \
0 -0.076349 -1.039129 0.000
1 0.163044 -1.324339 0.017
2 0.050779 -0.537230 0.033
3 -0.223424 -0.630582 0.050
4 -0.208525 -1.296504 0.067
... ... ... ...
1778 -0.166851 -1.083000 29.634
1779 1.436913 -1.265997 29.651
1780 1.634014 -0.130795 29.667
1781 0.923709 -0.212215 29.684
1782 -0.191012 -0.058644 29.701
acceleration_magnitude
0 1.112569
1 1.338316
2 0.879006
3 1.183290
4 1.461555
... ...
1778 1.182392
1779 1.979117
1780 1.689068
1781 1.315810
1782 1.260038
[1783 rows x 7 columns],
timestamp_ms timestamp_μs freeAcceleration_m/s²_x \
0 1746708388926 199427346 0.046509
1 1746708388943 199444013 0.040232
2 1746708388959 199460680 0.031789
3 1746708388976 199477347 0.140357
4 1746708388993 199494014 -0.065061
... ... ... ...
1786 1746708418693 229194608 -0.498794
1787 1746708418710 229211275 -0.424106
1788 1746708418727 229227942 -0.571897
1789 1746708418743 229244609 -0.149889
1790 1746708418760 229261276 -0.270612
freeAcceleration_m/s²_y freeAcceleration_m/s²_z time_s \
0 -0.049324 0.378253 0.000
1 -0.082570 0.300064 0.017
2 -0.056001 0.414821 0.033
3 0.047952 0.457452 0.050
4 -0.023433 0.105056 0.067
... ... ... ...
1786 -0.210728 -2.165378 29.767
1787 -0.477301 -1.594980 29.784
1788 -0.815092 -1.692597 29.801
1789 -1.471216 -2.034573 29.817
1790 -1.605592 -1.728581 29.834
acceleration_magnitude
0 0.384280
1 0.313807
2 0.419789
3 0.480897
4 0.125773
... ...
1786 2.232054
1787 1.718035
1788 1.963754
1789 2.515240
1790 2.374690
[1791 rows x 7 columns],
timestamp_ms timestamp_μs freeAcceleration_m/s²_x \
0 1747033013617 123566622 0.092350
1 1747033013634 123583289 0.308911
2 1747033013650 123599956 0.478206
3 1747033013667 123616623 0.230824
4 1747033013684 123633290 -0.022896
... ... ... ...
1783 1747033043334 153283883 0.467967
1784 1747033043351 153300550 0.476856
1785 1747033043368 153317217 0.809446
1786 1747033043384 153333884 1.358585
1787 1747033043401 153350551 1.458225
freeAcceleration_m/s²_y freeAcceleration_m/s²_z time_s \
0 0.311271 -0.020087 0.000
1 0.240814 -0.048132 0.017
2 0.176104 0.521458 0.033
3 0.107216 0.944909 0.050
4 -0.292477 1.117781 0.067
... ... ... ...
1783 -0.123759 0.294951 29.717
1784 -0.192136 0.000191 29.734
1785 -0.279738 0.055799 29.751
1786 -0.082746 0.192875 29.767
1787 0.042822 -0.078331 29.784
acceleration_magnitude
0 0.325302
1 0.394632
2 0.729117
3 0.978585
4 1.155639
... ...
1783 0.566838
1784 0.514109
1785 0.858236
1786 1.374700
1787 1.460955
[1788 rows x 7 columns],
timestamp_ms timestamp_μs freeAcceleration_m/s²_x \
0 1746704814859 209719360 0.047203
1 1746704814876 209736027 0.038527
2 1746704814892 209752694 0.040116
3 1746704814909 209769361 0.015788
4 1746704814926 209786028 0.013383
... ... ... ...
1782 1746704844560 239419954 1.038621
1783 1746704844576 239436621 1.016820
1784 1746704844593 239453288 1.064942
1785 1746704844610 239469955 1.247072
1786 1746704844626 239486622 1.264108
freeAcceleration_m/s²_y freeAcceleration_m/s²_z time_s \
0 -0.167005 0.283479 0.000
1 -0.128904 0.256366 0.017
2 -0.065615 0.185970 0.033
3 0.011174 0.267086 0.050
4 0.116792 0.386025 0.067
... ... ... ...
1782 -0.952962 -1.862821 29.701
1783 -0.380841 -0.648541 29.717
1784 -0.680544 -0.057891 29.734
1785 -0.734097 0.777641 29.751
1786 -1.198298 1.096929 29.767
acceleration_magnitude
0 0.332384
1 0.289524
2 0.201245
3 0.267786
4 0.403528
... ...
1782 2.336016
1783 1.264740
1784 1.265145
1785 1.642807
1786 2.058431
[1787 rows x 7 columns],
timestamp_ms timestamp_μs freeAcceleration_m/s²_x \
0 1747033772226 882164663 -0.323900
1 1747033772243 882181330 -0.362763
2 1747033772259 882197997 -0.291865
3 1747033772276 882214664 -0.151857
4 1747033772293 882231331 0.109761
... ... ... ...
1780 1747033801893 911831923 -1.488138
1781 1747033801910 911848590 -1.426718
1782 1747033801927 911865257 -1.696018
1783 1747033801943 911881924 -1.953311
1784 1747033801960 911898591 -1.848742
freeAcceleration_m/s²_y freeAcceleration_m/s²_z time_s \
0 0.258127 -0.177178 0.000
1 0.430727 -0.244325 0.017
2 0.627431 -0.266001 0.033
3 0.743734 -0.228697 0.050
4 0.631557 -0.220694 0.067
... ... ... ...
1780 0.771571 -2.830918 29.667
1781 0.979907 -2.799942 29.684
1782 0.627168 -2.471069 29.701
1783 0.224583 -1.783616 29.717
1784 0.127890 -1.260719 29.734
acceleration_magnitude
0 0.450480
1 0.613855
2 0.741357
3 0.792782
4 0.677951
... ...
1780 3.289981
1781 3.291719
1782 3.062026
1783 2.654646
1784 2.241342
[1785 rows x 7 columns]])
# Compare number of rows in each participant's data by plotting
import matplotlib.pyplot as plt
# Create a list to store the number of rows for each participant
num_rows_list_standard = [len(df) for df in dfs_stand]
num_rows_list_challenge = [len(df) for df in dfs_stand_challenge]
# PLot bar chart of number of rows for each participant with participant number on x-axis
plt.figure(figsize=(14, 6))
plt.bar(range(len(num_rows_list_standard)), num_rows_list_standard, label='Standard')
# Label each bar with the number of samples in the participant's data
for i, num_rows in enumerate(num_rows_list_standard):
plt.text(i, num_rows, str(num_rows), ha='center', va='bottom')
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Standard Task')
plt.legend()
<matplotlib.legend.Legend at 0x140ee20e0>
plt.figure(figsize=(12, 6))
plt.bar(range(len(num_rows_list_challenge)), num_rows_list_challenge, label='Challenge')
for i, num_rows in enumerate(num_rows_list_challenge):
plt.text(i, num_rows, str(num_rows), ha='center', va='bottom')
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Challenge Task')
plt.legend()
<matplotlib.legend.Legend at 0x140ee3d00>
# Plot a double, non overlapping bar chart of number of rows for standard and challenge tasks
count_df = pd.DataFrame({
'Standard': num_rows_list_standard,
'Challenge': num_rows_list_challenge
})
count_df.plot(kind='bar', figsize=(12, 6))
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Standard and Challenge Tasks')
plt.legend()
<matplotlib.legend.Legend at 0x140f47760>
# Calculate mean acceleration for each axis per participant
mean_acceleration_standard_x = [df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand]
mean_acceleration_challenge_x = [df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand_challenge]
mean_acceleration_standard_y = [df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand]
mean_acceleration_challenge_y = [df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand_challenge]
mean_acceleration_standard_z = [df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand]
mean_acceleration_challenge_z = [df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand_challenge]
# Plot and compare mean acceleration for each axis per participant
def plot_mean_acceleration(mean_acceleration_standard, mean_acceleration_challenge, axis='x'):
plt.figure(figsize=(12, 6))
plt.bar(range(len(mean_acceleration_standard)), mean_acceleration_standard, label='Standard')
plt.bar(range(len(mean_acceleration_challenge)), mean_acceleration_challenge, label='Challenge')
# Label each bar with the mean acceleration, rounded to 2 decimal places
for i, mean_acceleration in enumerate(mean_acceleration_standard):
# write text in blue color
plt.text(i, mean_acceleration, str(round(mean_acceleration, 4)), ha='center', va='bottom', color='blue')
for i, mean_acceleration in enumerate(mean_acceleration_challenge_x):
plt.text(i, mean_acceleration, str(round(mean_acceleration, 4)), ha='center', va='bottom', color='black')
plt.xlabel('Participant')
plt.ylabel(f"Mean Acceleration in {axis}-axis (m/s²)")
plt.title('Mean Acceleration in Standard and Challenge Tasks')
plt.legend()
# Mean acceleration for x axis
plot_mean_acceleration(mean_acceleration_standard_x, mean_acceleration_challenge_x, 'x')
# Mean acceleration for y axis
plot_mean_acceleration(mean_acceleration_standard_y, mean_acceleration_challenge_y, 'y')
# Mean acceleration for z axis
plot_mean_acceleration(mean_acceleration_standard_z, mean_acceleration_challenge_z, 'z')
# Plot sample means using qq plots
import statsmodels.api as sm
# Create a list to store the sample means for each participant
sample_means_standard_x = np.array([df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand])
sample_means_challenge_x = np.array([df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand_challenge])
sample_means_standard_y = np.array([df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand])
sample_means_challenge_y = np.array([df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand_challenge])
sample_means_standard_z = np.array([df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand])
sample_means_challenge_z = np.array([df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand_challenge])
fig, axs = plt.subplots(2, 3, figsize=(20, 12), sharex=True)
# Plot qq plot of sample means and add labels
sm.qqplot(sample_means_standard_x, line='45', fit=True, ax=axs[0, 0])
axs[0, 0].set_xlabel('Theoretical Quantiles')
axs[0, 0].set_ylabel('Sample Quantiles')
axs[0, 0].set_title('QQ Plot of Sample Means for Standard Task along x-axis')
axs[0, 0].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_x, line='45', fit=True, ax=axs[1, 0])
axs[1, 0].set_xlabel('Theoretical Quantiles')
axs[1, 0].set_ylabel('Sample Quantiles')
axs[1, 0].set_title('QQ Plot of Sample Means for Challenge Task along x-axis')
axs[1, 0].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_standard_y, line='45', fit=True, ax=axs[0, 1])
axs[0, 1].set_xlabel('Theoretical Quantiles')
axs[0, 1].set_ylabel('Sample Quantiles')
axs[0, 1].set_title('QQ Plot of Sample Means for Standard Task along y-axis')
axs[0, 1].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_y, line='45', fit=True, ax=axs[1, 1])
axs[1, 1].set_xlabel('Theoretical Quantiles')
axs[1, 1].set_ylabel('Sample Quantiles')
axs[1, 1].set_title('QQ Plot of Sample Means for Challenge Task along y-axis')
axs[1, 1].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_standard_z, line='45', fit=True, ax=axs[0, 2])
axs[0, 2].set_xlabel('Theoretical Quantiles')
axs[0, 2].set_ylabel('Sample Quantiles')
axs[0, 2].set_title('QQ Plot of Sample Means for Standard Task along z-axis')
axs[0, 2].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_z, line='45', fit=True, ax=axs[1, 2])
axs[1, 2].set_xlabel('Theoretical Quantiles')
axs[1, 2].set_ylabel('Sample Quantiles')
axs[1, 2].set_title('QQ Plot of Sample Means for Challenge Task along z-axis')
axs[1, 2].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:20: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[0, 0].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:27: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[1, 0].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:34: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[0, 1].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:41: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[1, 1].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:48: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[0, 2].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:55: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[1, 2].legend()
<matplotlib.legend.Legend at 0x14122a6e0>
# Calculate magnitude of acceleration for each participant
mean_acceleration_standard_magnitude = np.array([df['acceleration_magnitude'].mean() for df in dfs_stand])
mean_acceleration_challenge_magnitude = np.array([df['acceleration_magnitude'].mean() for df in dfs_stand_challenge])
mean_acceleration_standard_magnitude, mean_acceleration_challenge_magnitude
(array([1.78488787, 1.63689184, 1.39231585, 1.35709055, 1.45023621]), array([1.00407051, 1.23304809, 1.15220116, 0.69327856, 0.78111748]))
# Plot qq plot for mean acceleration of standard and challenge tasks
fig, axs = plt.subplots(1, 2, figsize=(20, 4), sharex=True)
# Plot qq plot for the mean magnitude of acceleration for standard and challenge tasks
sm.qqplot(mean_acceleration_standard_magnitude, line='45', fit=True, ax=axs[0])
axs[0].set_xlabel('Theoretical Quantiles')
axs[0].set_ylabel('Sample Quantiles')
axs[0].set_title('QQ Plot of Mean Magnitude of Acceleration for Standard Task')
axs[0].legend()
sm.qqplot(mean_acceleration_challenge_magnitude, line='45', fit=True, ax=axs[1])
axs[1].set_xlabel('Theoretical Quantiles')
axs[1].set_ylabel('Sample Quantiles')
axs[1].set_title('QQ Plot of Mean Magnitude of Acceleration for Challenge Task')
axs[1].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/205138737.py:8: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[0].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/205138737.py:14: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[1].legend()
<matplotlib.legend.Legend at 0x141433370>
# Plot ecdf of sample means
import seaborn as sns
# Plot ecdf of sample means using subplots of grid 1,3 along x, y and z axis
fig, axs = plt.subplots(1, 3, figsize=(20, 6), sharex=True)
sns.ecdfplot(sample_means_standard_x, label='Standard', ax=axs[0])
sns.ecdfplot(sample_means_challenge_x, label='Challenge', ax=axs[0])
axs[0].set_xlabel('Mean Acceleration along x-axis (m/s²)')
axs[0].set_ylabel('ECDF')
axs[0].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[0].legend()
sns.ecdfplot(sample_means_standard_y, label='Standard', ax=axs[1])
sns.ecdfplot(sample_means_challenge_y, label='Challenge', ax=axs[1])
axs[1].set_xlabel('Mean Acceleration along y-axis (m/s²)')
axs[1].set_ylabel('ECDF')
axs[1].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[1].legend()
sns.ecdfplot(sample_means_standard_z, label='Standard', ax=axs[2])
sns.ecdfplot(sample_means_challenge_z, label='Challenge', ax=axs[2])
axs[2].set_xlabel('Mean Acceleration along z-axis (m/s²)')
axs[2].set_ylabel('ECDF')
axs[2].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[2].legend()
<matplotlib.legend.Legend at 0x14111bd00>
fig, axs = plt.subplots(1, 2, figsize=(20, 4), sharex=True)
sns.ecdfplot(mean_acceleration_standard_magnitude, label='Standard', ax=axs[0])
sns.ecdfplot(mean_acceleration_challenge_magnitude, label='Challenge', ax=axs[1])
axs[0].set_xlabel('Mean Acceleration (m/s²)')
axs[0].set_ylabel('ECDF')
axs[0].set_title('ECDF of Mean Magnitude of Acceleration for Standard Task')
axs[0].legend()
axs[1].set_xlabel('Mean Acceleration (m/s²)')
axs[1].set_ylabel('ECDF')
axs[1].set_title('ECDF of Mean Magnitude of Acceleration for Challenge Task')
axs[1].legend()
<matplotlib.legend.Legend at 0x1410ff730>
# Perform t-test for the magnitude of mean acceleration of standard and challenge tasks
mean_acc_standard = [df['acceleration_magnitude'].mean() for df in dfs_stand]
mean_acc_challenge = [df['acceleration_magnitude'].mean() for df in dfs_stand_challenge]
print(mean_acc_standard)
print(mean_acc_challenge)
[np.float64(1.7848878692954853), np.float64(1.636891837767239), np.float64(1.3923158522778347), np.float64(1.3570905500926835), np.float64(1.4502362050831268)] [np.float64(1.0040705073076044), np.float64(1.2330480911660822), np.float64(1.1522011601310023), np.float64(0.6932785640948899), np.float64(0.7811174815974915)]
# Plot the magnitude of acceleration for each participant as a scatter plot
import matplotlib.pyplot as plt
participants = range(1, len(mean_acc_challenge) + 1)
plt.scatter(participants, mean_acc_standard, label='Standard')
plt.scatter(participants, mean_acc_challenge, label='Challenge')
<matplotlib.collections.PathCollection at 0x140df6020>
# Plot a bar chart of mean acceleration of standard and challenge tasks
participants = range(1, len(mean_acc_challenge) + 1)
plt.plot(participants, mean_acc_standard, marker='o', label='Standard')
plt.plot(participants, mean_acc_challenge, marker='o', label='Challenge')
plt.xlabel("Participant")
plt.ylabel("Mean Acceleration Magnitude")
plt.title("Sit-to-Stand: Standard vs Challenge")
plt.legend()
plt.grid(True)
plt.show()
# Paired t-test for the magnitude of mean acceleration of standard and challenge tasks
from scipy.stats import ttest_rel
t_stat, p_value = ttest_rel(mean_acc_standard, mean_acc_challenge)
print("Paired t-test result: \n")
print(f"t-statistic = {t_stat:.4f}")
print(f"p-value = {p_value:.4f}")
Paired t-test result: t-statistic = 5.5460 p-value = 0.0052
# Conclusion
print("Conclusion:")
print("*"*30)
if p_value < 0.05:
print("There is a significant difference in the mean acceleration magnitude between the standard and challenge tasks.")
else:
print("There is no significant difference in the mean acceleration magnitude between the standard and challenge tasks.")
Conclusion: ****************************** There is a significant difference in the mean acceleration magnitude between the standard and challenge tasks.